<?php

namespace App\Kuafu\Pay\Controller\Ext;

use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Base\Enum\BaseCodeEnum;
use App\Kuafu\Base\Util\EnvUtil;
use App\Kuafu\Common\Service\InformationPushService;
use App\Kuafu\CouponExt\Channel\MeiTuan\MeiTuanBase;
use App\Kuafu\Mybank\Controller\MybankEntryController;
use App\Kuafu\Mybank\Enum\MybankFunctionEnum;
use App\Kuafu\Mybank\Service\MybankCallbackService;
use App\Kuafu\Mybank\Service\MybankCashierOrderService;
use App\Kuafu\Mybank\Service\MybankEntryService;
use App\Kuafu\Mybank\Service\MybankOrderWithholdNotifyService;
use App\Kuafu\Mybank\Service\MybankOrderWithholdRefundNotifyService;
use App\Kuafu\Mybank\Service\MybankOrderWithholdService;
use App\Kuafu\Mybank\Service\MybankService;
use App\Kuafu\Pay\BasePay;
use App\Kuafu\Pay\Enum\AliPayEnum;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Model\RefundStreamModel;
use App\Kuafu\Pay\Service\PayService;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\User\Service\UserRoleService;
use App\Kuafu\WaiMai\Enum\WaiMaiDBEnum;
use App\Kuafu\WaiMai\Service\WaiMaiShopService;
use App\Library\FeiShu\SendFs;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Remote\Tiger\Appraise\AppraiseRemote;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;

class CallbackController extends BaseController
{
    public function wxPay(Request $request)
    {
        // TEST
        SendFs::newRobot()->setTitleContent('微信支付回调通知', json_encode(request()->all()))->send();

        Log::channel('pay')->info('wxPay Request=============:', $request->all());
//
//        // 解密
//        $inWechatpaySignature = '';// 请根据实际情况获取
//        $inWechatpayTimestamp = strtotime($request->post('create_time'));// 请根据实际情况获取
//        $inWechatpaySerial = '';// 请根据实际情况获取
//        $inWechatpayNonce = '';// 请根据实际情况获取
//        $inBody = $request->post('resource');// 请根据实际情况获取，例如: file_get_contents('php://input');
//
//        $apiv3Key = config('pay.wx.direct.api_key');// 在商户平台上设置的APIv3密钥
//
//// 根据通知的平台证书序列号，查询本地平台证书文件，
//// 假定为 `/path/to/wechatpay/inWechatpaySerial.pem`
//        $certInstance = PemUtil::loadCertificate(config('pay.wx.direct.ssl_cert_path'));
//
//// 检查通知时间偏移量，允许5分钟之内的偏移
//        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
//        $verifiedStatus = Rsa::verify(
//        // 构造验签名串
//            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
//            $inWechatpaySignature,
//            $certInstance
//        );
//        if ($timeOffsetStatus && $verifiedStatus) {
//            $inBodyArray = (array)json_decode($inBody, true);
//            ['resource' => [
//                'ciphertext'      => $ciphertext,
//                'nonce'           => $nonce,
//                'associated_data' => $aad
//            ]] = $inBodyArray;
//            $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
//            $inBodyResourceArray = (array)json_decode($inBodyResource, true);
//            var_dump($inBodyResourceArray);// 打印解密后的结果
//        }

        return $this->success();
    }

    /**
     * 富友支付回调
     * @param Request $request
     * @return int
     * @throws \App\Kuafu\Order\Exceptions\OrderException
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function fyPay(Request $request)
    {
        Log::channel('pay')->info('fyPay Request=============:', $request->all());

        PayService::sPayCallBackLog(PayStreamModel::PAY_CHANNEL_FY, $request->all());
        return 1;
    }

    /**
     * 美团绑定店铺
     * @param Request $request
     * @return string
     */
    public function mtStoreMap(Request $request)
    {
        Log::channel('pay')->info('mtStoreMap Request=============:', $request->all());

        SendFs::newRobot(SendFs::ROBOT_AUDIT)
              ->setTitleContent('美团团购绑定店铺回调通知', json_encode(request()->all(), JSON_UNESCAPED_UNICODE))
              ->send();

        list($appEnvInt, $shopId) = MeiTuanBase::decodeMTShopId((string)$request->post('ePoiId'));
        if ($appEnvInt != EnvUtil::intProd(config('app.env'))) {
            SendFs::newRobot()->setTitleContent('美团映射店铺回调 - 被驳回',
                "通知环境:" . EnvUtil::intToAppEnv($appEnvInt) . " 当前环境:" . config('app.env'))->send();
            return '{"data":"success"}';
        }

        $thirdShopId   = $request->post('ePoiId', '');
        $thirdShopName = $request->post('poiName', '');
        $businessId    = $request->post('businessId', '');
        $appAuthToken  = $request->post('appAuthToken', '');

        (new WaiMaiShopService($shopId))->bindMTCallback($thirdShopId, $thirdShopName, $businessId, $appAuthToken);

        $shop    = ShopService::getShopInfo($shopId);
        $userIds = UserRoleService::getShopManageList(config('merchant.manager_role_id'), [$shopId])['lists'] ?? [];
        InformationPushService::push(InformationPushService::MT_GROUP_OPEN_PUSH, array_column($userIds, 'userId'),
            $shop);

        //日常运营阶段 饿了么外卖上线&美团外卖上线「需推送」 点评团购上线&抖音团购上线「需推送」
        AppraiseRemote::waimaiNotify($shopId, WaiMaiDBEnum::SOURCE_TYPE_MT_TG, $thirdShopId);
        return '{"data":"success"}';
    }

    /**
     * 美团取消绑定店铺
     * @param Request $request
     * @return string
     */
    public function mtUnstoreMap(Request $request)
    {
        Log::channel('pay')->info('mtUnstoreMap Request=============:', $request->all());

        SendFs::newRobot(SendFs::ROBOT_AUDIT)
              ->setTitleContent('美团团购解绑店铺回调通知', json_encode(request()->all(), JSON_UNESCAPED_UNICODE))
              ->send();

        list($appEnvInt, $shopId) = MeiTuanBase::decodeMTShopId((string)$request->post('ePoiId'));
        if ($appEnvInt != EnvUtil::intProd(config('app.env'))) {
            SendFs::newRobot()->setTitleContent('美团解绑店铺回调 - 被驳回',
                "通知环境:" . EnvUtil::intToAppEnv($appEnvInt) . " 当前环境:" . config('app.env'))->send();
            return '{"data":"success"}';
        }

        $businessId = $request->post('businessId', '');

        (new WaiMaiShopService($shopId))->unbindMtCallback($businessId);

        return '{"data":"success"}';
    }

    /**
     * 支付宝app支付回调
     * @param Request $request
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function aliAppPay(Request $request)
    {
        Log::channel('pay')
           ->info('aliAppPay Request=============:', ['body' => $request->all(), 'header' => $request->header()]);
        $tradeStatus = $request->get('trade_status');

        if ($tradeStatus == AliPayEnum::TRADE_STATUS_OK) {

            // 支付成功
            PayService::sPayCallBackLog(PayStreamModel::PAY_CHANNEL_ALI, $request->all());
        }

        return 'success';
    }

    /**
     * 微信app支付回调
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Kuafu\Pay\Exceptions\PayException
     */
    public function wxAppPay(Request $request, int $sysType)
    {
        Log::channel('pay')
           ->info('wxAppPay Request=============:', ['body' => $request->all(), 'header' => $request->header()]);

        PayService::sPayCallBackLog(PayStreamModel::PAY_CHANNEL_WX, $request->all(), $sysType);

        return $this->success();
    }

    /**
     * 微信app支付回调v2
     * @param Request $request
     * @param int $sysType
     * @param int $company
     */
    public function wxAppPayV2(Request $request, int $sysType, int $company)
    {
        Log::channel('pay')
           ->info('wxAppPayV2 Request=============:', ['body' => $request->all(), 'header' => $request->header()]);

        PayService::sPayCallBackLog(PayStreamModel::PAY_CHANNEL_WX, $request->all(), $sysType, $company);

        return $this->success();
    }

    /**
     * 网商银行业务处理回调
     *
     * @param Request $request
     * @return Application|ResponseFactory|Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function mybank(Request $request)
    {
        logMsg("网商回调原始数据写入", ["originalData" => $request->getContent()]);
        $mybankRequest = simplexml_load_string($request->getContent());
        $resultJson    = json_decode(json_encode($mybankRequest), 1);
        logMsg("网商回调解析数据写入", ["parsedData" => $resultJson]);

        $functionName    = attributeGet($resultJson, "request.head.Function", null);
        $asyncNotifyType = attributeGet($resultJson, "request.body.AsyncNotifyType", null);
        logMsg("网商回调事件写入", compact("functionName", "asyncNotifyType"));
        Log::channel('mybank')->info('mybank:' . $functionName, [
            'all' => $resultJson,
        ]);

        $statusCode = ResponseAlias::HTTP_OK;
        switch ($functionName) {
            case MybankFunctionEnum::MERCHANTPROD_MERCH_NOTIFY://预入驻业务回调
                switch ($asyncNotifyType) {
                    case "PRE_REGISTER_ASYNC_NOTIFY"://预入驻结果通知
                        MybankEntryService::preRegisterAsyncNotify((object)$resultJson["request"]["body"]);
                        break;
                    case "PRE_REGISTER_ACTIVATE_ASYNC_NOTIFY"://预入驻激活结果通知
                        MybankEntryService::preRegisterActiveAsyncNotify((object)$resultJson["request"]["body"]);
                        break;
                }
                break;
            case MybankFunctionEnum::MERCHANTPROD_MERCHANT_ARRANGEMENT_INFO_NOTIFY://授权｜取消授权协商代扣
                MybankEntryService::arrangementNotify((object)$resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_BILLPAY_BATCH_FINISH_NOTIFY://批次完结通知接口
                list($statusCode, $result) = MybankService::batchFinishNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_CHANNEL_VOSTRO_NOTIFY://渠道结算入账通知接口
                list($statusCode, $result) = MybankService::channelVostroNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_PROTOCOL_WITHHOLD_RESULT_NOTIFY:// 协议代扣通知
                (new MybankOrderWithholdNotifyService($resultJson["request"]["body"]))->handle();
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_PROTOCOL_WITHHOLD_REFUND_RESULT_NOTIFY:// 协议代扣通知
                (new MybankOrderWithholdRefundNotifyService($resultJson["request"]["body"]))->handle();
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_MERCHANT_ACCOUNT_UNFREEZE_NOTIFY:// 余额解冻通知
                list($statusCode, $result) = MybankOrderWithholdService::unfreezeNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_VOSTRO_NOTIFY://来帐汇入通知接口
                list($statusCode, $result) = MybankService::vostroNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_WITHDRAW_NOTIFY://提现结果通知接口
                list($statusCode, $result) = MybankService::withdrawNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_REFUND_NOTIFY://充值退款结果通知接口-提现的另一种方式
                list($statusCode, $result) = MybankService::refundNotify($resultJson["request"]["body"]);
                break;
            case MybankFunctionEnum::BKCLOUDFUNDS_UNIFIED_ORDER_NOTIFY:// 网商小程序支付-统一支付结果通知
                list($statusCode, $result) = MybankCashierOrderService::unifiedOrderNotify($resultJson['request']['body']);
                break;
        }

        $returnXml = MybankCallbackService::returnSuccessXml($resultJson);

        return response($returnXml, $statusCode)->header("Content-type", "text/xml");
    }
}
